package com.wocai.jrt.orgadmin.orders.action;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.vteba.utils.common.BigDecimalUtils;
import com.vteba.utils.common.PropsUtils;
import com.vteba.utils.id.ObjectId;
import com.vteba.web.action.GenericAction;
import com.vteba.web.action.JsonBean;
import com.vteba.web.editer.StringEditor;
import com.wocai.jrt.orgadmin.employee.bean.EmpGroupTreeBean;
import com.wocai.jrt.orgadmin.employee.model.Employee;
import com.wocai.jrt.orgadmin.employee.model.EmployeeCommissionHistoryBean;
import com.wocai.jrt.orgadmin.employee.model.EmployeeVisit;
import com.wocai.jrt.orgadmin.employee.service.spi.EmployeeCommissionHistoryService;
import com.wocai.jrt.orgadmin.employee.service.spi.EmployeeGroupService;
import com.wocai.jrt.orgadmin.employee.service.spi.EmployeeService;
import com.wocai.jrt.orgadmin.employee.service.spi.EmployeeVisitService;
import com.wocai.jrt.orgadmin.investor.bean.EmpBreifBean;
import com.wocai.jrt.orgadmin.message.model.MessageLog;
import com.wocai.jrt.orgadmin.message.service.spi.MessageLogService;
import com.wocai.jrt.orgadmin.orders.bean.OfflineApplyReqBean;
import com.wocai.jrt.orgadmin.orders.bean.OfflineApplyResBean;
import com.wocai.jrt.orgadmin.orders.bean.OfflineOrderReqBean;
import com.wocai.jrt.orgadmin.orders.bean.OrderDetailResBean;
import com.wocai.jrt.orgadmin.orders.bean.OrderOfflineApplyResBean;
import com.wocai.jrt.orgadmin.orders.bean.OrderPaySerialResBean;
import com.wocai.jrt.orgadmin.orders.bean.OrderReqBean;
import com.wocai.jrt.orgadmin.orders.bean.OrderResBean;
import com.wocai.jrt.orgadmin.orders.bean.OrderVisitResBean;
import com.wocai.jrt.orgadmin.orders.bean.ProductBreifBean;
import com.wocai.jrt.orgadmin.orders.model.Orders;
import com.wocai.jrt.orgadmin.orders.model.PayTypeAudit;
import com.wocai.jrt.orgadmin.orders.model.Voucher;
import com.wocai.jrt.orgadmin.orders.service.spi.OrdersService;
import com.wocai.jrt.orgadmin.orders.service.spi.PayTypeAuditService;
import com.wocai.jrt.orgadmin.orders.service.spi.VoucherService;
import com.wocai.jrt.orgadmin.product.model.Product;
import com.wocai.jrt.orgadmin.product.model.ProductGrade;
import com.wocai.jrt.orgadmin.product.service.spi.ProductGradeService;
import com.wocai.jrt.orgadmin.product.service.spi.ProductService;
import com.wocai.jrt.orgadmin.utils.ImgType;
import com.wocai.jrt.orgadmin.utils.MessagePush;
import com.wocai.jrt.orgadmin.utils.MyFileUtils;
import com.wocai.jrt.orgadmin.utils.UserUtils;

/**
 * 订单控制器
 * 
 * @author yinlei
 * @date 2015-8-4 19:44:34
 */
@Controller
@RequestMapping("/orders")
public class OrdersAction extends GenericAction<Orders> {
	public static final String IMAGES_URL = PropsUtils.get("images.url");
	private static final Logger LOGGER = LoggerFactory.getLogger(OrdersAction.class);
	private static final int STATE_REDEEM = 3;
	private static final int STATE_CANCLE = 5;
	private static final int STATE_PAYED = 1;
	private static final Pattern IMAGE = Pattern
			.compile("^[\u4e00-\u9fffa-zA-Z0-9_\\(\\)\\-\\s.]+.(jpg|jpeg|gif|png|bmp)$");
	private static final Pattern CONTACT = Pattern
			.compile("^[\u4e00-\u9fffa-zA-Z0-9_\\(\\)\\-\\s.]+.pdf$");
	
	@Inject
	private ProductService productServiceImpl;

	@Inject
	private EmployeeCommissionHistoryService employeeCommissionHistoryServiceImpl;
	
	@Inject
	private VoucherService voucherServiceImpl;

	@Inject
	private OrdersService ordersServiceImpl;
	
	@Inject
	private EmployeeVisitService employeeVisitServiceImpl;
	
	@Inject
	private EmployeeGroupService employeeGroupServiceImpl;
	
	@Inject
	private PayTypeAuditService payTypeAuditServiceImpl;
	
	@Inject
	private EmployeeService employeeServiceImpl;
	
	@Inject
	private MessageLogService messageLogServiceImpl;
	
	@Inject
	private ProductGradeService productGradeServiceImpl;
	
	@InitBinder(value={"orderTime","payTime"})
	protected void initBinder1(WebDataBinder binder) {
		binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss"), true));
	}
	@InitBinder(value={"orderTimeStart","orderTimeEnd"})
	protected void initBinder2(WebDataBinder binder) {
		binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(
				"yyyy-MM-dd"), true));
	}
	@InitBinder
	protected void initBinder3(WebDataBinder binder) {
		binder.registerCustomEditor(String.class, new StringEditor());
	}
	/**
	 * 获得订单List页面。
	 * 
	 * @param model
	 *            参数
	 * @return 订单List页面
	 */
	@RequestMapping("/list")
	public String list(OrderReqBean model, Map<String, Object> maps) {
		return "orders/list";
	}
	
	/**
	 * 跳转线下订单添加页面。
	 * 
	 * @param model
	 *            参数
	 * @return 订单List页面
	 */
	@RequestMapping("/entering")
	public String entering(OrderReqBean model, Map<String, Object> maps) {
		return "orders/entering";
	}
	
	
	/**
	 * 获取团队树。
	 * 
	 * @param model
	 *            参数
	 * @return 团队树
	 */
	@ResponseBody
	@RequestMapping("/groupTree")
	public EmpGroupTreeBean groupTree() {
		EmpGroupTreeBean modelBean = employeeGroupServiceImpl.tree(UserUtils.getOrgId());
		return modelBean;
	}
	
	/**
	 * 执行实际的新增操作
	 * 
	 * @param model
	 *            要新增的数据
	 * @return 新增页面逻辑视图
	 */
	@ResponseBody
	@RequestMapping("/doAdd")
	public JsonBean doAdd(
			@Valid OfflineOrderReqBean model,
			@RequestParam(value = "paySignUser", required = false) MultipartFile paySignUser,
			@RequestParam(value = "idcardFront", required = false) MultipartFile idcardFront,
			@RequestParam(value = "idcardBack", required = false) MultipartFile idcardBack,
			@RequestParam(value = "bankCard", required = false) MultipartFile bankCard,
			BindingResult errors) {
		JsonBean json = new JsonBean();
		try {
			// 对入参对象绑定参数验证
			if (errors.hasErrors()) {
				json.setCode(0);
				json.setMessage("parameter valid failure！");
				LOGGER.error("parameter valid failure, model = [{}]", JSON.toJSONString(model));
				return json;
			}
			if(null == paySignUser || null == idcardFront || null == idcardBack){
				json.setCode(0);
				json.setMessage("请确认所需上传文件准确无误");
				return json;
			}
			if(!CONTACT.matcher(paySignUser.getOriginalFilename()).matches()){
				json.setCode(0);
				json.setMessage("上传合同文件格式必须为PDF");
				return json;
			}
			Date now = new Date();
			if(model.getOrderTime().after(now)){
				json.setCode(0);
				json.setMessage("下单时间不能大于当前时间");
				return json;
			}
			if(model.getPayTime().after(now)){
				json.setCode(0);
				json.setMessage("支付时间不能大于当前时间");
				return json;
			}
			if(model.getPayTime().before(model.getOrderTime())){
				json.setCode(0);
				json.setMessage("支付时间不能小于下单时间");
				return json;
			}
			json = ordersServiceImpl.addOfflineOrder(model, paySignUser, idcardFront, idcardBack, bankCard);
		} catch (IOException e) {
			json.setCode(0);
			json.setMessage("save orders error");
			LOGGER.error("save orders error, msg = [{}]", e.getMessage());
		}
		return json;
	}

	/**
	 * 查询订单List，Json格式。
	 * 
	 * @param model
	 *            参数
	 * @return 订单List
	 */
	@ResponseBody
	@RequestMapping(value = "/query", method = RequestMethod.POST)
	public Map<String, Object> query(@RequestBody OrderReqBean model) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			model.setOrgId(UserUtils.getOrgId());
			model.setOrderBy("FIELD(o.state, 5) ASC,order_time desc");
			Date orderEnd = model.getOrderTimeEnd();
			if (orderEnd != null) {
				DateTime date = new DateTime(orderEnd);
				date = date.plusDays(1).minusMillis(1);
				model.setOrderTimeEnd(date.toDate());
			}
			LOGGER.info("获取订单的model参数: [{}]",JSON.toJSONString(model));
			List<OrderResBean> list = ordersServiceImpl.getOrderResBeanList(model);
			// 统计的时候，不需要分页
			model.setPage(null);
			long totalRecord = ordersServiceImpl.countByOrgId(model);

			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("order query success.");
			}

			// jQuery datatable 就是这样的参数，阿西吧
			// result.put("sEcho", user.getEcho());// 这个参数要回传，但是好像也不需要，阿西吧
			result.put("aaData", list); // 返回的数据
			result.put("iTotalRecords", totalRecord); // 总记录数
			result.put("iTotalDisplayRecords", totalRecord); // 显示的记录数
		} catch (Exception e) {
			LOGGER.error("order query error, msg=[{}]", e.getMessage());
		}
		return result;
	}
	

	/**
	 * 执行实际的新增联系记录
	 * 
	 * @param model
	 *            要新增的联系记录
	 * @return 新增结果
	 */
	@ResponseBody
	@RequestMapping("/addVisit")
	public JsonBean addVisit(@RequestBody EmployeeVisit model) {
		JsonBean bean = new JsonBean();
		if (StringUtils.isAnyBlank(model.getContent(), model.getInvestorId(), model.getOrderId())) {
			LOGGER.info("params is null");
			bean.setCode(0);
			bean.setMessage("参数不能为空");
			return bean;
		}
		try {
			model.setId(ObjectId.get().toString());
			model.setVisitTime(new Date());
			LOGGER.info("新增联系记录参数: [{}]",JSON.toJSONString(model));
			int result = employeeVisitServiceImpl.save(model);
			if (result == 1) {
				bean.setCode(1);
				bean.setMessage(SUCCESS);
				LOGGER.info("add visit success!");
			} else {
				bean.setCode(0);
				bean.setMessage(ERROR);
				LOGGER.info("add visit error!");
			}
		} catch (Exception e) {
			LOGGER.error("visit add error, msg=[{}]", e.getMessage());
			bean.setCode(0);
			bean.setMessage(ERROR);
		}
		return bean;
	}

	/**
	 * 获得订单详情，Json格式。
	 * 
	 * @param id
	 *            订单id
	 * @return 订单详情-供添加联系记录使用的model
	 */
	@RequestMapping("/detail/{id}")
	public String detail(@PathVariable("id") String id, Map<String, Object> maps) {
		OrderDetailResBean model = null;
		try {
			OrderReqBean orderReqBean = new OrderReqBean();
			orderReqBean.setId(id);
			orderReqBean.setOrgId(UserUtils.getOrgId());
			LOGGER.info("query order detail param: [{}]",JSON.toJSONString(orderReqBean));
			model = ordersServiceImpl.getOrderDetial(orderReqBean);
			maps.put("model", model);
		} catch (Exception e) {
			LOGGER.error("get record list error, errorMsg=[{}].", e.getMessage());
			return "common/error";
		}
		return "orders/detail";
	}

	/**
	 * 查看订单详情页。
	 * 
	 * @param model
	 *            查询参数，携带ID
	 * @return 订单详情页
	 */
	@ResponseBody
	@RequestMapping("/orderDetail")
	public OrderDetailResBean orderDetail(@RequestBody OrderResBean orderResBean) {
		OrderDetailResBean model = null;
		EmployeeCommissionHistoryBean com = new EmployeeCommissionHistoryBean();
		com.createCriteria().andOrderIdEqualTo(orderResBean.getId());
		try {
			OrderReqBean orderReqBean = new OrderReqBean();
			orderReqBean.setId(orderResBean.getId());
			orderReqBean.setOrgId(UserUtils.getOrgId());
			LOGGER.info("query order detail param: [{}]",JSON.toJSONString(orderReqBean));
			model = ordersServiceImpl.getOrderDetial(orderReqBean);
			long payCount = ordersServiceImpl.countPaySerialNumByOrderId(orderResBean.getId());
			long payContacts = ordersServiceImpl.countVisitNumByOrderId(orderResBean.getId());
			long payCommission = employeeCommissionHistoryServiceImpl.count(com);
			model.setPayCount(payCount);
			model.setPayContacts(payContacts);
			model.setPayCommission(payCommission);
			Voucher v = new Voucher();
			v.setOrderId(model.getOrderId());
			List<Voucher> voucherList = voucherServiceImpl.queryList(v);
			model.setVoucherList(voucherList);
			model.setVoucherCount(voucherList.size());
			if(model.getOrderAmount() != null){
				try {
					model.setSubFeeTotal(BigDecimalUtils.multiply(model.getSubFee(), model.getOrderAmount()));
				} catch (NullPointerException e) {
					LOGGER.error("caculate subfee error, msg=[{}]", e.getMessage());
				}
			}else{
				model.setSubFeeTotal(0.0);
			}
			if(null != model.getAgentId()){
				try {
					model.setAgentName(employeeServiceImpl.get(model.getAgentId()).getName());
				} catch (Exception e) {
					LOGGER.error("get agent employee name error, errorMsg=[{}].", e.getMessage());
				}
			}
			LOGGER.info("order detail result: [{}]",JSON.toJSONString(model));
		} catch (Exception e) {
			LOGGER.error("order query error, msg=[{}]", e.getMessage());
		}
		return model;
	}

	/**
	 * 赎回订单。
	 * 
	 * @param model
	 *            取消参数，携带ID
	 * @return 操作情况
	 */
	@ResponseBody
	@RequestMapping("/redeem")
	public JsonBean redeem(@RequestBody OrderResBean orderResBean) {
		JsonBean json = new JsonBean();
		try {
			Orders model = ordersServiceImpl.get(orderResBean.getId());
			model.setState(STATE_REDEEM);
			LOGGER.info("redeem order param: [{}]",JSON.toJSONString(model));
			int result = ordersServiceImpl.updateById(model);
			if (result > 0) {
				json.setCode(1);
				json.setMessage(SUCCESS);
				LOGGER.info("redeem order success!");
			} else {
				json.setCode(0);
				json.setMessage(ERROR);
				LOGGER.info("redeem order error!");
			}
		} catch (Exception e) {
			LOGGER.error("redeem order error, msg=[{}]", e.getMessage());
			json.setCode(0);
			json.setMessage(ERROR);
		}
		return json;
	}

	/**
	 * 取消订单。
	 * 
	 * @param model
	 *            取消参数，携带ID
	 * @return 操作情况
	 */
	@ResponseBody
	@RequestMapping("/cancle")
	public JsonBean cancle(@RequestBody OrderResBean orderResBean) {
		JsonBean json = new JsonBean();
		try {
			LOGGER.info("cancel order param: [{}]",JSON.toJSONString(orderResBean));
			Orders model = ordersServiceImpl.get(orderResBean.getId());
			Double orderAmount = model.getOrderAmount();

			String productId = model.getProductId();
			Product product = productServiceImpl.get(productId);

			// 释放份额，修改状态
			if (null != orderAmount) {
				Product productParam = new Product();
				productParam.setId(productId);
				productParam.setAvailable(BigDecimalUtils.add(product.getAvailable(), orderAmount));
				productServiceImpl.updateById(productParam);
			}
			
			model.setState(STATE_CANCLE);
			LOGGER.info("update order state param: [{}]",JSON.toJSONString(model));
			int result = ordersServiceImpl.updateById(model);
			if (result > 0) {
				json.setCode(1);
				json.setMessage(SUCCESS);
				json.setData(model);
				LOGGER.info("cancle order success!");
			} else {
				json.setCode(0);
				json.setMessage(ERROR);
				LOGGER.info("cancle order error!");
			}
		} catch (Exception e) {
			LOGGER.error("cancle order error, msg=[{}]", e.getMessage());
			json.setCode(0);
			json.setMessage(ERROR);
			LOGGER.info("cancle order error!");
		}
		return json;
	}
	
	/**
	 * 删除订单。
	 * 
	 * @param model
	 *            删除参数，携带ID
	 * @return 操作情况
	 */
	@ResponseBody
	@RequestMapping("/delete")
	public JsonBean delete(@RequestBody OrderResBean orderResBean) {
		JsonBean json = new JsonBean();
		try {
			LOGGER.info("delete order param: [{}]",JSON.toJSONString(orderResBean));
			Orders model = ordersServiceImpl.get(orderResBean.getId());
			Double orderAmount = model.getOrderAmount();

			String productId = model.getProductId();
			Product product = productServiceImpl.get(productId);

			// 取消的订单不用释放份额，未支付的订单需要释放份额
			if(model.getState() != STATE_CANCLE){
				if (null != orderAmount) {
					Product productParam = new Product();
					productParam.setId(productId);
					productParam.setAvailable(BigDecimalUtils.add(product.getAvailable(), orderAmount));
					productServiceImpl.updateById(productParam);
				}
			}
			
			model.setDeleted(true);
			LOGGER.info("update order state param: [{}]",JSON.toJSONString(model));
			int result = ordersServiceImpl.updateById(model);
			if (result > 0) {
				json.setCode(1);
				json.setMessage(SUCCESS);
				json.setData(model);
				LOGGER.info("delete order success!");
			} else {
				json.setCode(0);
				json.setMessage(ERROR);
				LOGGER.info("delete order error!");
			}
		} catch (Exception e) {
			LOGGER.error("delete order error, msg=[{}]", e.getMessage());
			json.setCode(0);
			json.setMessage(ERROR);
			LOGGER.info("delete order error!");
		}
		return json;
	}

	/**
	 * 查看联系记录。
	 * 
	 * @param orderResBean
	 *            查询参数，携带ID
	 * @return 联系记录list
	 */
	@ResponseBody
	@RequestMapping("/contacts")
	public Map<String, Object> contacts(@RequestBody OrderResBean orderResBean) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			List<OrderVisitResBean> list = new ArrayList<OrderVisitResBean>();
			orderResBean.setOrderBy("ev.visit_time desc");
			// 统计的时候，不需要分页
			LOGGER.info("query order contacts param: [{}]",JSON.toJSONString(orderResBean));
			long totalRecord = ordersServiceImpl.countVisitNumByOrderId(orderResBean.getId());
			if (totalRecord > 0) {
				list = ordersServiceImpl.getOrderVisitList(orderResBean);
			} else {
				list = null;
			}

			LOGGER.info("order detail contacts counts " + totalRecord);
			// jQuery datatable 就是这样的参数，阿西吧
			// result.put("sEcho", user.getEcho());// 这个参数要回传，但是好像也不需要，阿西吧
			result.put("aaData", list); // 返回的数据
			result.put("iTotalRecords", totalRecord); // 总记录数
			result.put("iTotalDisplayRecords", totalRecord); // 显示的记录数
		} catch (Exception e) {
			LOGGER.error("order query error, msg=[{}]", e.getMessage());
		}
		return result;
	}

	/**
	 * 查看交易流水。
	 * 
	 * @param orderResBean
	 *            查询参数，携带ID
	 * @return 交易流水列表
	 */
	@ResponseBody
	@RequestMapping("/pay")
	public Map<String, Object> pay(@RequestBody OrderResBean orderResBean) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			
			List<OrderPaySerialResBean> list = new ArrayList<OrderPaySerialResBean>();
			orderResBean.setOrderBy("p.pay_time desc");
			// 统计的时候，不需要分页
			LOGGER.info("query order pay param: [{}]",JSON.toJSONString(orderResBean));
			long totalRecord = ordersServiceImpl.countPaySerialNumByOrderId(orderResBean.getId());
			if (totalRecord > 0) {
				list = ordersServiceImpl.getOrderPaySerial(orderResBean);
			} else {
				list = null;
			}
			LOGGER.info("order detail pay serial counts " + totalRecord);
			// jQuery datatable 就是这样的参数，阿西吧
			// result.put("sEcho", user.getEcho());// 这个参数要回传，但是好像也不需要，阿西吧
			result.put("aaData", list); // 返回的数据
			result.put("iTotalRecords", totalRecord); // 总记录数
			result.put("iTotalDisplayRecords", totalRecord); // 显示的记录数
		} catch (Exception e) {
			LOGGER.error("order query error, msg=[{}]", e.getMessage());
		}
		return result;
	}
	
	/**
	 * 查询机构下的产品。
	 * 
	 * @param employeeKey
	 * @return List<EmpBreifBean>
	 */
	@ResponseBody
	@RequestMapping("/product/{productKey}/{type}")
	public List<ProductBreifBean> product(@PathVariable("productKey") String productKey,@PathVariable(value="type") Integer type) {
		JsonBean bean = new JsonBean();
		try {
			// 查询该机构下所有理财师列表
			List<ProductBreifBean> eBean = ordersServiceImpl.getOrgProductList(
					UserUtils.getOrgId(), productKey,type);
			return eBean;
		} catch (Exception e) {
			bean.setCode(0);
			bean.setMessage("获取机构产品列表失败: [{}]" + e.getMessage());
			LOGGER.error("get product list error, errorMsg=[{}].", e.getMessage());
		}
		return null;
	}
	
	@ResponseBody
	@RequestMapping("/productGrade/{id}")
	public List<ProductGrade> productGrade(@PathVariable("id") String id) {
		JsonBean bean = new JsonBean();
		try {
			ProductGrade productGrade = new ProductGrade();
			productGrade.setProductId(id);
			// 查询该机构下所有理财师列表
			List<ProductGrade> eBean = productGradeServiceImpl.queryList(productGrade);
			return eBean;
		} catch (Exception e) {
			bean.setCode(0);
			bean.setMessage("获取产品档次列表失败: [{}]" + e.getMessage());
			LOGGER.error("get product grade error, errorMsg=[{}].", e.getMessage());
		}
		return null;
	}
	
	/**
	 * 查询机构下的理财师。
	 * 
	 * @param employeeKey
	 * @return List<EmpBreifBean>
	 */
	@ResponseBody
	@RequestMapping("/employee/{employeeKey}")
	public List<EmpBreifBean> employee(@PathVariable("employeeKey") String employeeKey) {
		JsonBean bean = new JsonBean();
		try {
			// 查询该机构下所有理财师列表
			List<EmpBreifBean> eBean = ordersServiceImpl.getOrgEmployeeList(
					UserUtils.getOrgId(), employeeKey);
			return eBean;
		} catch (Exception e) {
			bean.setCode(0);
			bean.setMessage("获取机构理财师列表失败: [{}]" + e.getMessage());
			LOGGER.error("get Investor list error, errorMsg=[{}].", e.getMessage());
		}
		return null;
	}

	/***
	 * 下载文件 用@RequestParam注解来指定表单上的file为MultipartFile
	 * 
	 * @param filePath
	 * @return file
	 */
	@ResponseBody
	@RequestMapping("/downloadFile")
	public JsonBean downloadFile(String filePath, HttpServletResponse response) {
		JsonBean jsonBean = new JsonBean();
		try {
			// 发起请求的参数
			LOGGER.info("request file download, url=[{}]", filePath);

			MyFileUtils.downloadFile(filePath, response);

			// 封装jsonBean
			jsonBean.setCode(1);
			jsonBean.setMessage(SUCCESS);

		} catch (Exception e) {
			LOGGER.error("download file error, error=[{}]", e.getMessage());
			jsonBean.setCode(0);
			jsonBean.setMessage("download file error");
		}

		return jsonBean;
	}
	
	/**
	 * 获取线下支付申请详情。
	 * 
	 * @param model
	 *            取消参数，携带ID
	 * @return 操作情况
	 */
	@ResponseBody
	@RequestMapping("/offlinePayAudit")
	public JsonBean offlinePayAudit(String id) {
		JsonBean json = new JsonBean();
		try {
			LOGGER.info("audit order offline pay apply param: [{}]",JSON.toJSONString(id));
			OfflineApplyResBean offlineApplyResBean = new OfflineApplyResBean();
			try {
				offlineApplyResBean = ordersServiceImpl.fetchOfflineApplyResBean(id).get(0);
			} catch (Exception e) {
				offlineApplyResBean = null;
			}
			json.setCode(1);
			json.setMessage(SUCCESS);
			json.setData(offlineApplyResBean);
		} catch (Exception e) {
			LOGGER.error("fetch order error, msg=[{}]", e.getMessage());
			json.setCode(0);
			json.setMessage(ERROR);
		}
		return json;
	}
	
	/**
	 * 订单详情-查看线下支付申请。
	 * 
	 * @param model
	 *            取消参数，携带ID
	 * @return 操作情况
	 */
	@ResponseBody
	@RequestMapping("/checkOfflineApply")
	public JsonBean checkOfflineApply(String id) {
		JsonBean json = new JsonBean();
		try {
			LOGGER.info("audit order offline pay apply param: [{}]",JSON.toJSONString(id));
			OrderOfflineApplyResBean orderOfflineApplyResBean = new OrderOfflineApplyResBean();
			try {
				orderOfflineApplyResBean = ordersServiceImpl.fetchOrderOfflineApplyResBean(id).get(0);
				PayTypeAudit pay = new PayTypeAudit();
				pay.setOrderId(id);
				orderOfflineApplyResBean.setPayTypeAuditList(payTypeAuditServiceImpl.queryList(pay));
			} catch (Exception e) {
				LOGGER.error("fetch order error, msg=[{}]", e.getMessage());
				orderOfflineApplyResBean = null;
			}
			json.setCode(1);
			json.setMessage(SUCCESS);
			json.setData(orderOfflineApplyResBean);
		} catch (Exception e) {
			LOGGER.error("fetch order error, msg=[{}]", e.getMessage());
			json.setCode(0);
			json.setMessage(ERROR);
		}
		return json;
	}
	
	/**
	 * 审核线下支付申请。
	 * 
	 * @param model
	 *            取消参数，携带ID
	 * @return 操作情况
	 */
	@ResponseBody
	@RequestMapping("/offlineApplyAudit")
	public JsonBean offlineApplyAudit(@RequestBody OfflineApplyReqBean offlineApplyReqBean) {
		JsonBean json = new JsonBean();
		try {
			String id = offlineApplyReqBean.getId();
			Boolean result = offlineApplyReqBean.getResult();
			LOGGER.info("audit order offline pay apply param: [{}]",JSON.toJSONString(id + " + " + result));
			PayTypeAudit payTypeAudit = payTypeAuditServiceImpl.get(id);
			Orders o = new Orders();
			if(payTypeAudit == null){
				json.setCode(0);
				json.setMessage("找不到该条申请记录");
				return json;
			}else{
				//查询出申请的订单
				o.setOrderId(payTypeAudit.getOrderId());
				o = ordersServiceImpl.unique(o);
				if(o == null){
					json.setCode(0);
					json.setMessage("申请记录对应订单无效");
					return json;
				}
				if(true == result){
					//设置订单审核通过 
					o.setOfflineAudit(3);
					//设置申请审核记录
					payTypeAudit.setResult(result);
					payTypeAudit.setAuditId(UserUtils.getUserId());
					payTypeAudit.setAuditName(UserUtils.getUser().getName());
					payTypeAudit.setAuditTime(new Date());
				}else{
					//设置审核未通过
					o.setOfflineAudit(2);
					//设置申请审核记录
					payTypeAudit.setResult(result);
					payTypeAudit.setAuditId(UserUtils.getUserId());
					payTypeAudit.setAuditName(UserUtils.getUser().getName());
					payTypeAudit.setAuditTime(new Date());
				}
				//通知理财师申请成功 根据条件
				String employeeId = payTypeAudit.getEmployeeId();
				Employee emp = employeeServiceImpl.get(employeeId);
				if (null != emp) {
					// 向团队负责人推送员工签到消息
					MessageLog message = new MessageLog();
					message.setId(ObjectId.get().toString());
					message.setEmployeeId(UserUtils.getUserId());
					message.setSender("机构后台");
					message.setSource("机构后台");
					message.setSkipType(1);
					message.setMessageType(3);
					message.setSkipKey(payTypeAudit.getOrderId());
					message.setType(2);
					message.setCreateTime(new Date());
					message.setState(0);
					message.setOrgId(emp.getOrgId());
					Date date = new Date();
					message.setCreateTime(date);
					if(true == result){
						message.setMessage("您申请开通的其它支付方式，已经申请通过，请到我的订单查看");
					}else{
						message.setMessage("您申请开通其它支付方式，审核未通过");
					}
					int re = messageLogServiceImpl.save(message);
					if (re == 1) {
						LOGGER.info("message for offline apply audit success");
					} else {
						LOGGER.error("message for offline apply audit error");
					}
					// 极光向接收人推送消息
					MessagePush messagePush = new MessagePush(message.getMessage(),"机构消息");
					Set<String> alias = new HashSet<String>();
					alias.add(employeeId);
					messagePush.sendPushAlias(alias);
				}
				int r = ordersServiceImpl.updateById(o);
				int s = payTypeAuditServiceImpl.updateById(payTypeAudit);
				if(1 == r && 1 == s){
					json.setCode(1);
					json.setMessage(SUCCESS);
					return json;
				}
			}
		} catch (Exception e) {
			LOGGER.error("change apply audit state error, msg=[{}]", e.getMessage());
			json.setCode(0);
			json.setMessage(ERROR);
		}
		return json;
	}
	
	/**
	 * 上传图片组件
	 * 
	 * @param model
	 *            要更新的关于我们信息，含有ID
	 * @return 操作结果信息
	 */
	@ResponseBody
	@RequestMapping("/imgUploads")
	public JsonBean imgUploads(@RequestParam("file[]") List<MultipartFile> file,String id) {
		getHttpServletResponse().setHeader("X-Frame-Options", "SAMEORIGIN");
		JsonBean bean = new JsonBean();
		id = id.split(",")[0];
		if(null == id){
			bean.setCode(0);
			bean.setMessage("订单id不能为空");
			return bean;
		}
		Orders order = ordersServiceImpl.get(id);
		if(null == order){
			bean.setCode(0);
			bean.setMessage("订单id无效");
			return bean;
		}
		Voucher v = new Voucher();
		try {
			if (file.size() != 0) {
				//先删除所有原来订单所有的凭证
				Voucher preVou = new Voucher();
				preVou.setOrderId(order.getOrderId());
				List<Voucher> preVoucherList = voucherServiceImpl.pagedList(preVou);
				Iterator<Voucher> iter = preVoucherList.iterator();
				while (iter.hasNext()) {
					String path = iter.next().getFilePath();
					File img = new File(IMAGES_URL + path);
					if (img.exists()) {
						img.delete();
					}
				}
				int r = voucherServiceImpl.deleteBulks(preVou);
				LOGGER.info("删除了原先=[{}]个凭证", r);
				// spring mvc已经配置了，这里再次控制一下
				for(int i = 0;i < file.size();i++){
					MultipartFile f = file.get(i);
					if (f.getSize() > (1024 * 1024 * 1024 * 2L)) { // 2M
						bean.setCode(0);
						bean.setMessage("图片大小不能大于2M！"); // 参数错误
						return bean;
					}
					String fileName = f.getOriginalFilename();
					// 正则判断图片
					if (IMAGE.matcher(fileName).matches()) {
						LOGGER.info("request file upload, filename=[{}]", f.getOriginalFilename());
						// 上传图片
						String filePath = MyFileUtils.uploadImg(f,ImgType.VOUCHER);
						LOGGER.info("upload file success, filePath=[{}]", filePath);
						v.setId(ObjectId.get().toString());
						v.setCreateTime(new Date());
						v.setFilePath(filePath);
						v.setOrderId(order.getOrderId());
						v.setOrgId(order.getOrgId());
						v.setEmployeeId(UserUtils.getUserId());
						int result = voucherServiceImpl.save(v);
						if(1 > result){
							bean.setCode(0);
							bean.setMessage("上传成功，但是保存至错误，请联系相关人员");
							LOGGER.error("save voucher error.");
							return bean;
						}
					} else {
						// 不是图片，清空掉，不处理
						bean.setCode(0);
						bean.setMessage("上传的图片格式有问题！");
						LOGGER.error("上传的图片格式有问题！.图片次序为："+i);
						return bean;
					}
				}
				bean.setCode(1);
				bean.setMessage(SUCCESS);
			}
		} catch (Exception e) {
			bean.setCode(0);
			bean.setMessage("添加图片失败");
			LOGGER.error("save record error.", e.getMessage());
		}
		order.setUploadVoucher(true);
		order.setOfflinePay(true);
		order.setState(STATE_PAYED);
		order.setPayTime(new Date());
		order.setPaidAmount(order.getOrderAllAmount());
		ordersServiceImpl.updateById(order);
		return bean;
	}
}
